{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##   课程练习：\n",
    "1.   编写一个程序，将字符串s中的字符颠倒过来。<br>\n",
    "(1) 采用倒序迭代方式进行程序编写。<br>\n",
    "(2) 采用递归方式进行函数设计。\n",
    "2.   编写squeeze(s1,s2)函数，将s1中任意与s2中匹配的字符都删除。 \n",
    "3.   编写expand(s1,s2)函数，将s1中类似于\"a-z\",\"0-9\"一类的速记符号在字符串s2中扩展为等价的列表\"abcd......xyz\",\"0123456789\"。<br>\n",
    "注：正则表达式（regexp）的一部分知识点，应多留意，对工作十分有用。\n",
    "4.   编写rightrot(x,k)函数，将x的二进制位循环向右移动k位（移除的k个二进制位放到x的最左边）。\n",
    "5.   定义宏（预处理指令）swap(a,b), 交换变量a,b的值。\n",
    "6.   编写一个文档解析程序，按单词出现的**频率**降序打印出单词列表。<br>\n",
    "注：单词可能存在拼写错误，尝试给出拼写错误检查的解决方案。\n",
    "   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//1.1 采用倒序迭代方式进行程序编写。\n",
    "#include <stdio.h>\n",
    "void inverse_s(char a[],char b[]){\n",
    "    int i,k;\n",
    "    for(i=0;a[i]!='\\0';i++);\n",
    "    i--;\n",
    "    for(k=0;i>=0;i--,k++) b[k]=a[i];\n",
    "    b[k]='\\0';\n",
    "}\n",
    "// 1.2 采用递归方式进行函数设计。\n",
    "int len=0;\n",
    "void inverse(char a[],char b[],int k){\n",
    "    if(a[k]=='\\0'){\n",
    "    b[k]='\\0';\n",
    "    return;    \n",
    "    }\n",
    "    inverse(a,b,k+1);\n",
    "    b[len++]=a[k];\n",
    "}\n",
    "int main(){\n",
    "    char* s1 = \"!samtsirhC yrreM\";\n",
    "    char s2[30];\n",
    "    inverse(s1,s2,0);\n",
    "    printf(\"%s\\n\",s2);\n",
    "    int i;\n",
    "    for(i=0;i<30;i++) s2[i]=0;\n",
    "    inverse_s(s1,s2);\n",
    "    printf(\"%s\\n\",s2);\n",
    "    \n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//2  编写squeeze(s1,s2)函数，将s1中任意与s2中匹配的字符都删除。\n",
    "#include <stdio.h>\n",
    "void sqeeze(char s1[],char s2[]){\n",
    "    int b,s,j,k=0;\n",
    "    while(s2[k]!='\\0'){\n",
    "        for(j=0;s1[j]!='\\0';j++){\n",
    "            if(s1[j]==s2[k]){\n",
    "                b=1;\n",
    "                break;\n",
    "            } \n",
    "        }\n",
    "        if(b==1)\n",
    "        for(s=k;s2[s]!='\\0';s++) s2[s]=s2[s+1];\n",
    "        else\n",
    "        k++;\n",
    "        b=0;\n",
    "    }\n",
    "    \n",
    "}\n",
    "\n",
    "int main(){\n",
    "    char* a = \"eyri\";\n",
    "    char b[30]=\"Merry Christmas!\";\n",
    "    sqeeze(a,b);\n",
    "    printf(\"%s\\n\",b);\n",
    "    return 0;\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//3  编写expand(s1,s2)函数，将s1中类似于\"a-z\",\"0-9\"一类的速记符号在字符串s2中扩展为等价的列表\"abcd......xyz\",\"0123456789\"。\n",
    "#include <stdio.h>\n",
    "void expand(char s1[],char s2[]){\n",
    "    int i=0,j=0,k=0;\n",
    "    char s,t;\n",
    "    while(s1[i]!='\\0'){\n",
    "        if(s1[i+1]!='\\0'&&s1[i+2]!='\\0'&&s1[i+1]=='-'){\n",
    "            if((s1[i]<=s1[i+2])&&(((s1[i]>='a')&&(s1[i+2]<='z'))||((s1[i]>='A')&&(s1[i+2]<='Z'))||((s1[i]>='0')&&(s1[i+2]<='9')))){\n",
    "                for(k=0;k<(s1[i+2]-s1[i]+1);k++) s2[j++]=s1[i]+k;\n",
    "                i+=3;\n",
    "            }\n",
    "        }else{\n",
    "            s2[j++]=s1[i++];\n",
    "        }\n",
    "    }\n",
    "   s2[j]='\\0';  \n",
    "}\n",
    "int main(){\n",
    "    char* a=\"Our course is just the a-c to become proficient programmers! You have to finish a-z and 0-9 yourself!\";\n",
    "    char b[300];\n",
    "    expand(a,b);\n",
    "    printf(\"%s\\n\",b);\n",
    "    return 0;\n",
    "    \n",
    "}\n",
    "               \n",
    "               \n",
    "               \n",
    "               "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//编写rightrot(x,k)函数，将x的二进制位循环向右移动k位（移除的k个二进制位放到x的最左边）。\n",
    "#include <stdio.h>\n",
    "void p_digit(unsigned char b){\n",
    "    if(b==0){ \n",
    "        return;\n",
    "    }\n",
    "    p_digit(b/2);\n",
    "    printf(\"%d\",b%2);    \n",
    "}\n",
    "\n",
    "void rightrot(unsigned char* x,int k){\n",
    "    int len = sizeof(unsigned char)*8; \n",
    "    k=k%len;\n",
    "    *x=((*x)>>k)|((*x)<<(len-k));\n",
    "}\n",
    "\n",
    "int main(){\n",
    "    unsigned char a=1;\n",
    "    p_digit(a),printf(\"\\n\");\n",
    "    rightrot(&a,5);\n",
    "    p_digit(a),printf(\"\\n\");\n",
    "    return 0;\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//5 定义宏（预处理指令）swap(a,b), 交换变量a,b的值。\n",
    "#include <stdio.h>\n",
    "#define swap(a,b) do{\\\n",
    "                      a^=b;\\\n",
    "                      b^=a;\\\n",
    "                      a^=b;\\\n",
    "                     }while(0)\n",
    "int main(){\n",
    "    char a = 'a';\n",
    "    char b = 'z';\n",
    "    swap(a,b);\n",
    "    printf(\"%c,%c\\n\",a,b);\n",
    "    \n",
    "    \n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "//6 编写一个文档解析程序，按单词出现的频率降序打印出单词列表\n",
    "#include <stdio.h>\n",
    "#include <string.h>\n",
    "#include <malloc.h>\n",
    "typedef struct LinkList{\n",
    "  char word[50];\n",
    "  int times;\n",
    "  struct LinkList* next;  \n",
    "} LinkList; \n",
    "int is_letter(char s){\n",
    "    if((s>='a')&&(s<='z'))\n",
    "        return 1;\n",
    "    if((s>='A')&&(s<='Z'))\n",
    "        return 1;\n",
    "    return 0;\n",
    "   }\n",
    "char lowercase(char c){\n",
    "    if((c>='a')&&(c<='z')) return c;\n",
    "    if((c>='A')&&(c<='Z')) return c+('a'-'A');\n",
    "    else return c;\n",
    "}\n",
    "int getword(FILE* fp, char* word){\n",
    "    char c;\n",
    "    int k=0;\n",
    "    while(!is_letter(c=getc(fp))&&c!=EOF);\n",
    "    do{\n",
    "       word[k++]=lowercase(c); \n",
    "    }while(is_letter(c=getc(fp))||c=='+'||c=='#');\n",
    "    if(k==1&&word[0]=='s') return 0;\n",
    "    if(c==EOF) return EOF;\n",
    "    word[k]='\\0';\n",
    "    return k;\n",
    "}\n",
    "LinkList* find_word(LinkList* linklist,char* word){\n",
    "    for(;linklist->next!=NULL;linklist=linklist->next)\n",
    "        if(!strcmp(word,linklist->word)){\n",
    "            linklist->times+=1;\n",
    "            return linklist;\n",
    "            }\n",
    "    if(linklist->next==NULL){\n",
    "        if(!strcmp(word,linklist->word)){\n",
    "            linklist->times+=1;\n",
    "            return linklist;\n",
    "        }\n",
    "        linklist->next =(LinkList* ) malloc(sizeof(LinkList));\n",
    "        if(linklist->next==NULL) return NULL;\n",
    "        linklist=linklist->next;\n",
    "        linklist->next=NULL;\n",
    "        linklist->times=1;\n",
    "        strcpy(linklist->word,word);\n",
    "        return linklist;    \n",
    "    }\n",
    "}\n",
    "LinkList* linklist;\n",
    "FILE* fp;\n",
    "int main(){\n",
    "    int b;\n",
    "    char word[50];\n",
    "    fp=fopen(\"documents.txt\",\"r\");\n",
    "    linklist=(LinkList*) malloc(sizeof(LinkList));\n",
    "    linklist->next=NULL;\n",
    "    linklist->times=0;\n",
    "    int word_num=0;\n",
    "    LinkList* temp=NULL;\n",
    "    while((b=getword(fp,word))!=EOF){\n",
    "        if(b) {\n",
    "               temp=find_word(linklist,word);\n",
    "               if(temp!=NULL&&temp->times==1) word_num++;\n",
    "        }\n",
    "        }\n",
    "    LinkList** links= (LinkList** ) malloc(sizeof(LinkList*)*word_num);\n",
    "    int i=0,j=0;\n",
    "    for(temp=linklist;temp->next!=NULL;temp=temp->next)\n",
    "        links[i++]=temp;\n",
    "    \n",
    "    for(j=word_num-1;j>1;j--)\n",
    "        for(i=1;i<j;i++)\n",
    "            if(links[i]->times<links[i+1]->times){\n",
    "                temp=links[i];\n",
    "                links[i]=links[i+1];\n",
    "                links[i+1]=temp;\n",
    "            }\n",
    "    fclose(fp);\n",
    "    fp=fopen(\"results.txt\",\"w\");\n",
    "    for(i=1;i<word_num;i++)\n",
    "    fprintf(fp,\"Word \\\"%s\\\" repeated %d times. \\n\",links[i]->word,links[i]->times);\n",
    "    fclose(fp);\n",
    "    for(i=0;i<word_num;i++)\n",
    "    free(links[i]);\n",
    "    free(links);        \n",
    "return 0;\n",
    "\n",
    "}\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C",
   "language": "c",
   "name": "c"
  },
  "language_info": {
   "file_extension": ".c",
   "mimetype": "text/plain",
   "name": "c"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
